home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / utility / 681 / scrnsavr / faze.s < prev    next >
Encoding:
Text File  |  1992-05-11  |  16.8 KB  |  546 lines

  1. *-------------------------------------*
  2. *    -F-A-Z-E- Screen Saver          *
  3. *      by Damien M. Jones          *
  4. *         Version 1.00          *
  5. *-------------------------------------*
  6.  
  7. *    This screen saver is built around a generic screen saver
  8. *    frame.  The frame hooks into the VBL and KBD/MIDI interrupts,
  9. *    displays a successful installation message, and then terminates
  10. *    with ptermres.
  11. *
  12. *    I've gone through (May 12, 1992) and added extra comments to
  13. *    clear up some confusion.  The separate parts of the program
  14. *    have been more clearly labeled.  If you don't like the way
  15. *    I format my assembly, tough; I write it for me, not for you.
  16.  
  17. *    Code begins.
  18.  
  19. *    Generic Screen Saver
  20. *    by Damien M. Jones
  21. *    Copyright 1992 Damien M. Jones, All Rights Reserved.
  22. *
  23. *    Just change the "saver" routine to change the screen saver.
  24. *    Please include a note in your documentation that you used
  25. *    the "Generic Screen Saver Frame by dmj"; I place no other
  26. *    restrictions on the use of this code.  So you could release
  27. *    a Shareware screen saver using this code, and you wouldn't
  28. *    have to send me a penny.  A copy of the screensaver would
  29. *    be nice, but not mandatory.
  30.  
  31. *    If you leave the "id" string as it is, you can use the BoinkCfg
  32. *    program to set the time delay for the screen saver, as well
  33. *    as disable it.  Otherwise, you'll have to write your own
  34. *    config program.
  35.  
  36. *    You'll need to change the amount of memory to save, around line
  37. *    182.  Faze uses a 32K screen, plus space for the program.
  38.  
  39.     jmp install        ; Install program.
  40.  
  41. *    Variables (for the config program).
  42.  
  43. id    dc.b 'dmjScreenSaver'    ; Fourteen-byte ID string.
  44. ssave    dc.w 0            ; Old screen address.
  45. screen    dc.w 0            ; Address of screen saver screen.
  46. timeout    dc.w 300        ; Default is two minutes.
  47. count    dc.w 300        ; Number of cycles left to wait.
  48. flag    dc.w 0            ; Set if screen saver active.
  49. palsave    dc.w 0,0,0,0,0,0,0,0    ; Place to store system palette.
  50.     dc.w 0,0,0,0,0,0,0,0
  51. rezsave    dc.w 0            ; Place to store system resolution.
  52. pal    dc.w $000,$722,$631,$540,$450,$361,$272,$163 ; Screensaver palette.
  53.     dc.w $054,$045,$136,$227,$316,$405,$504,$613
  54. rez    dc.w 0            ; Resolution of screen saver.
  55. rndseed    dc.l $31415926        ; Random number generator seed.
  56.  
  57. *    The VBL.  Decrements timer, then checks to see if screen saver
  58. *    needs to be activated.  It then jumps to the OS VBL.
  59.  
  60. vbl    tst.w flag        ; Is the screen saver active?
  61.     beq vskip        ; No, need to check counter.
  62.  
  63.     jsr saver        ; Call the screen save subroutine.
  64.     bra jmp1        ; All done.
  65.  
  66. vskip    move.l a0,-(a7)        ; Save this register.
  67.     move.l #count,a0    ; Address of count variable.
  68.  
  69.     subq.w #1,(a0)        ; Decrement counter.
  70.     tst.w (a0)+        ; Is it zero?
  71.     bne vblend        ; Nope, exit now.
  72.  
  73.     st (a0)            ; Set in-use flag.
  74.     movem.l d0/a1,-(a7)    ; Save these register too.
  75.     lea $FFFF8240.w,a1    ; Address of palette registers.
  76.     move.l #palsave,a0    ; Address to save into.
  77.  
  78.     move.l (a1)+,(a0)+    ; Save palette.
  79.     move.l (a1)+,(a0)+
  80.     move.l (a1)+,(a0)+
  81.     move.l (a1)+,(a0)+
  82.     move.l (a1)+,(a0)+
  83.     move.l (a1)+,(a0)+
  84.     move.l (a1)+,(a0)+
  85.     move.l (a1)+,(a0)+
  86.     move.w (a1)+,(a0)+    ; Resolution.
  87.  
  88.     lea $FFFF8240.w,a1    ; Address of palette registers.
  89.  
  90.     move.l (a0)+,(a1)+    ; Move in saver palette.
  91.     move.l (a0)+,(a1)+
  92.     move.l (a0)+,(a1)+
  93.     move.l (a0)+,(a1)+
  94.     move.l (a0)+,(a1)+
  95.     move.l (a0)+,(a1)+
  96.     move.l (a0)+,(a1)+
  97.     move.l (a0)+,(a1)+
  98.     move.b (a0),(a1)    ; And saver resolution.
  99.  
  100.     lea $FFFF8201.w,a1    ; Screen address vars in Shifter.
  101.     move.l #ssave,a0    ; Address of variable.
  102.     movep.w 0(a1),d0    ; Read old value.
  103.     move.w d0,(a0)+        ; And save it.
  104.     move.w (a0),d0        ; Get saver screen address.
  105.     movep.w d0,0(a1)    ; Copy over address.
  106.  
  107.     movem.l (a7)+,d0/a1    ; Restore registers.
  108.  
  109. vblend    move.l (a7)+,a0        ; Restore register.
  110. jmp1    jmp $11111111        ; Jump to old VBL.
  111.  
  112. *    The keyboard interrupt.  Resets VBL timer, and shuts off screen
  113. *    saver if it's active.
  114.  
  115. kbd    move.l a0,-(a7)        ; Save this register.
  116.  
  117.     move.l #timeout,a0    ; Address of variable.
  118.     move.w (a0)+,(a0)+    ; Copy over word.
  119.  
  120.     tst.w (a0)+        ; Was the screen saver active?
  121.     beq kbdend        ; No, exit now.
  122.  
  123.     movem.l d0/a1,-(a7)    ; Save these registers too.
  124.     lea $FFFF8240.w,a1    ; Address of palette registers.
  125.  
  126.     move.l (a0)+,(a1)+    ; Restore palette.
  127.     move.l (a0)+,(a1)+
  128.     move.l (a0)+,(a1)+
  129.     move.l (a0)+,(a1)+
  130.     move.l (a0)+,(a1)+
  131.     move.l (a0)+,(a1)+
  132.     move.l (a0)+,(a1)+
  133.     move.l (a0)+,(a1)+
  134.     move.b (a0),(a1)    ; Restore resolution.
  135.  
  136.     lea $FFFF8201.w,a1    ; Screen address vars in Shifter.
  137.     move.l #ssave,a0    ; Address of variable.
  138.     move.w (a0),d0        ; Get contents.
  139.     movep.w d0,0(a1)    ; Copy over address.
  140.  
  141.     clr.w flag        ; Clear this flag.
  142.     movem.l (a7)+,d0/a1    ; Restore these registers.
  143.  
  144. kbdend    move.l (a7)+,a0        ; Restore register.
  145. jmp2    jmp $11111111        ; Jump to old KBD.
  146.  
  147. *    The installation routine.  Displays install message, hooks into
  148. *    KBD/MIDI and VBL, and exits with ptermres.
  149.  
  150. install    pea initmsg        ; Address of text.
  151.     move.w #9,-(a7)        ; cconws
  152.     trap #1            ; GEMDOS(9)
  153.     addq.l #6,a7        ; Adjust stack.
  154.  
  155.     move.w #4,-(a7)        ; getrez
  156.     trap #14        ; XBIOS(4)
  157.     addq.l #2,a7        ; Adjust stack.
  158.  
  159.     cmp.b #2,d0        ; High resolution?
  160.     bne color        ; No, install and exit.
  161.  
  162.     pea errmsg        ; Address of text.
  163.     move.w #9,-(a7)        ; cconws
  164.     trap #1            ; GEMDOS(9)
  165.     addq.l #6,a7        ; Adjust stack.
  166.  
  167.     clr.w -(a7)        ; pterm0
  168.     trap #1            ; GEMDOS(0) - No return.
  169.  
  170. color    pea init        ; Address of init routine.
  171.     move.w #38,-(a7)    ; supexec
  172.     trap #14        ; XBIOS(38)
  173.     addq.l #6,-(a7)        ; Adjust stack.
  174.  
  175.     bsr sinit        ; Init Screen Saver.
  176.  
  177.     pea okmsg        ; Address of text.
  178.     move.w #9,-(a7)        ; cconws
  179.     trap #1            ; GEMDOS(9)
  180.     addq.l #6,a7        ; Adjust stack.
  181.  
  182.     move.l #34080,-(a7)    ; Save 33K for program & screen.
  183.     move.w #49,-(a7)    ; ptermres
  184.     trap #1            ; GEMDOS(49) - No return.
  185.  
  186. *    This actually hooks the interrupts.
  187.  
  188. init    movem.l d0/a0,-(a7)    ; Save this register.
  189.     move.w sr,-(a7)        ; Save status register.
  190.     move.w #$2700,sr    ; No interruptions.
  191.  
  192.     move.l #jmp2+2,a0    ; Address of jump instruction.
  193.     move.l $118.w,(a0)    ; Copy over old keyboard vector.
  194.     move.l #kbd,a0        ; Address of KBD routine.
  195.     move.l a0,$118.w    ; Store it.
  196.  
  197.     move.l #jmp1+2,a0    ; Address of jump instruction.
  198.     move.l $70.w,(a0)    ; Copy over old VBL vector.
  199.     move.l #vbl,a0        ; Address of VBL routine.
  200.     move.l a0,$70.w        ; Store it.
  201.  
  202.     move.l #svscrn,d0    ; Address of screen area.
  203.     add.l #255,d0        ; Round up if necessary.
  204.     lsr.l #8,d0        ; Shift that address down.
  205.     move.w d0,screen    ; Save screen address.
  206.  
  207.     move.w (a7)+,sr        ; Restore status register.
  208.     movem.l (a7)+,d0/a0    ; Restore this register.
  209.     rts            ; Return.
  210.  
  211. *    Init custom to FAZE.  Different screen savers will require
  212. *    different init code here.
  213.  
  214. sinit    clr.l d0        ; Make sure all of this is clear.
  215.     move.w screen,d0    ; Get screen address.
  216.     lsl.l #8,d0        ; Shift it to get real address.
  217.     move.l d0,a0        ; Copy to address register.
  218.  
  219.     move.w #7679,d1        ; Number of words.
  220.     move.l #-1,d2        ; Word to move.
  221.  
  222. siloop    move.l d2,(a0)+        ; Store word.
  223.     dbra d1,siloop        ; Next long.
  224.  
  225.     rts            ; All done.
  226.  
  227. *    The actual saver routine; it makes the screen saver what it is.
  228. *    This routine, the one above it, and the amount of memory to
  229. *    save on line 182 are all you need to change to make a different
  230. *    screen saver.
  231.  
  232. *    -F-A-Z-E- Screen Save Routine
  233. *    by Damien M. Jones
  234. *    Copyright 1992 Damien M. Jones, All Rights Reserved.
  235.  
  236. *    Basically, this program picks a random point from 0,0 to 31,31.
  237. *    It then checks the adjacent four points.  If any of these are
  238. *    in the next lower color, nothing is done.  Otherwise, if two
  239. *    of the connecting points are of the next higher color, then
  240. *    the point is plotted in that next higher color.  Otherwise it
  241. *    has a 20% chance of being plotted in that next higher color.
  242. *    Colors wrap, so 1 is the next higher color after 15.
  243.  
  244. *    Only one point is tested per VBL.  This routine takes about
  245. *    11% of processor time.
  246.  
  247. saver    movem.l d0-d7/a0-a2,-(a7) ; Save registers.
  248.  
  249.     bsr rnd            ; Randomize.
  250.  
  251.     clr.l d0        ; Make sure all of this is clear.
  252.     move.w screen,d0    ; Get screen address.
  253.     lsl.l #8,d0        ; Shift it to get real address.
  254.     move.l d0,a0        ; Copy to address register.
  255.  
  256. Faze    bsr rnd            ; Get a random number.
  257.     move.w d0,d3        ; Save it...
  258.     and.w #$1F,d3        ; 0-31, please.
  259.  
  260.     bsr rnd            ; Another random number.
  261.     move.w d0,d4        ; Save it...
  262.     and.w #$1F,d4        ; 0-31, please.
  263.  
  264.     move.w d4,-(a7)        ; Y coordinate.
  265.     move.w d3,-(a7)        ; X coordinate.
  266.     bsr A_ptst        ; Determine color of point.
  267.     addq.l #4,a7        ; Adjust stack.
  268.  
  269.     move.w d0,d5        ; Copy over the color.
  270.     clr.w d6        ; Points in lower color (0)
  271.     clr.w d7        ; Points in higher color (0)
  272.  
  273.     move.w d3,-(a7)        ; Save this.
  274.     subq.w #1,d3        ; Check point to the left.
  275.     tst.w d3        ; Less than zero?
  276.     bpl FSkip1        ; No.
  277.     beq FSkip1        ; No.
  278.     add.w #32,d3        ; Wrap.
  279. FSkip1    bsr FPoint        ; Check the point.
  280.     move.w (a7)+,d3        ; Restore value.
  281.  
  282.     move.w d4,-(a7)        ; Save this.
  283.     subq.w #1,d4        ; Check point above.
  284.     tst.w d4        ; Less than zero?
  285.     bpl FSkip2        ; No.
  286.     beq FSkip2        ; No.
  287.     add.w #32,d4        ; Wrap.
  288. FSkip2    bsr FPoint        ; Check the point.
  289.     move.w (a7)+,d4        ; Restore value.
  290.  
  291.     move.w d3,-(a7)        ; Save this.
  292.     addq.w #1,d3        ; Check point to the right.
  293.     bsr FPoint        ; Check the point.
  294.     move.w (a7)+,d3        ; Restore value.
  295.  
  296.     move.w d4,-(a7)        ; Save this.
  297.     addq.w #1,d4        ; Check point below.
  298.     bsr FPoint        ; Check the point.
  299.     move.w (a7)+,d4        ; Restore value.
  300.  
  301.     tst.w d6        ; Any lower color points here?
  302.     beq FSkip5        ; Nope, so far, so good.
  303.  
  304.     bra send        ; Else return now.
  305.  
  306. FSkip5    cmp.w #1,d7        ; 2 or more higher points?
  307.     bgt FPlot        ; Yes, plot away!
  308.  
  309.     bsr rnd            ; Get a random number.
  310.  
  311.     and.w #$FF,d0        ; Just the low byte.
  312.     cmp.w #204,d0        ; In the top 80%?
  313.     bgt FPlot        ; Yes, okay to plot the point.
  314.  
  315.     bra send        ; Else return now.
  316.  
  317. FPlot    move.w d3,d6        ; Copy the X coordinate.
  318.  
  319.     addq.w #1,d5        ; Next color up.
  320.     cmp.w #16,d5        ; Is it color 16?
  321.     bne FPLoop        ; Nope.
  322.     moveq.w #1,d5        ; Reset this to 1.
  323.  
  324. FPLoop    move.w d5,-(a7)        ; Point color.
  325.     move.w d4,-(a7)        ; Y Coordinate.
  326.     move.w d3,-(a7)        ; X Coordinate.
  327.     bsr A_plot        ; Plot the point.
  328.     addq.l #6,a7        ; Adjust stack.
  329.  
  330.     add.w #32,d3        ; Next column.
  331.     cmp.w #320,d3        ; Off the right edge?
  332.     blt FPLoop        ; No, do next point.
  333.  
  334.     move.w d6,d3        ; Move back to left edge.
  335.     add.w #32,d4        ; Next line.
  336.     cmp.w #192,d4        ; Off the bottom?
  337.     blt FPLoop        ; No, do the next point.
  338.  
  339. send    movem.l (a7)+,d0-d7/a0-a2 ; Restore registers.
  340.     rts            ; We're done now!
  341.  
  342. *    Test the color of a neighbor point, tally up.
  343.  
  344. FPoint    move.w d4,-(a7)        ; Y coordinate.
  345.     move.w d3,-(a7)        ; X coordinate.
  346.     bsr A_ptst        ; Determine color of point.
  347.     addq.l #4,a7        ; Adjust stack.
  348.  
  349.     sub.w d5,d0        ; Subtract out the original color.
  350.     cmp.w #14,d0        ; The edge.
  351.     bne FSkip3        ; Not here.
  352.     move.w #-1,d0
  353. FSkip3    cmp.w #-14,d0        ; The other edge.
  354.     bne FSkip4        ; Not here.
  355.     move.w #1,d0
  356.  
  357. FSkip4    tst.w d0        ; Show me a sign!
  358.     bpl FHigh        ; Next higher color.
  359.     bmi FLow        ; Next lower color.
  360.     rts            ; Same color.
  361.  
  362. FHigh    addq.w #1,d7        ; One more high point.
  363.     rts
  364.  
  365. FLow    addq.w #1,d6        ; One more low point.
  366.     rts
  367.  
  368. *    Assembler Line-A Replacement Plotter (low res _only_!)
  369. *    a0 contains address of screen.  ~C:A_plot(X&,Y&,C&)
  370.  
  371. A_plot    move.l a7,a1        ; Copy over stack pointer.
  372.     lea vtable(pc),a2    ; Address of vertical table.
  373.     clr.l d1
  374.  
  375.     move.w 4(a1),d0        ; X coordinate.
  376.     move.w 6(a1),d1        ; Y coordinate.
  377.     move.w 8(a1),d2        ; Color.
  378.  
  379.     lsl.w #1,d1        ; Double Y-coord for lookup.
  380.     move.l a0,a1        ; Copy over the address.
  381.     move.w 0(a2,d1.w),d1    ; Move in the Y-offset.
  382.     add.l d1,a1        ; Add in the vertical offset.
  383.  
  384.     move.w d0,d1        ; Copy the X-coord.
  385.     lsr.w #4,d1        ; Shift down.
  386.     lsl.w #3,d1        ; Shift up.
  387.     add.l d1,a1        ; Add in the horizontal offset.
  388.  
  389.     and.w #$F,d0        ; Take just the low nibble.
  390.     eor.w #$F,d0        ; Invert it.
  391.     btst #3,d0        ; In the higher byte?
  392.     bne flowb        ; Yes.
  393.  
  394.     addq.l #1,a1        ; Increment address.
  395.  
  396. flowb    btst #0,d2        ; Check out the bit.
  397.     beq aclr1        ; It's clear, clear the bit.
  398.     bset d0,(a1)        ; Set the bit.
  399.     bra askip1        ; Next plane.
  400. aclr1    bclr d0,(a1)        ; Clear the bit.
  401. askip1    addq.l #2,a1        ; Increment address.
  402.  
  403.     btst #1,d2        ; Check out the bit.
  404.     beq aclr2        ; It's clear, clear the bit.
  405.     bset d0,(a1)        ; Set the bit.
  406.     bra askip2        ; Next plane.
  407. aclr2    bclr d0,(a1)        ; Clear the bit.
  408. askip2    addq.l #2,a1        ; Increment address.
  409.  
  410.     btst #2,d2        ; Check out the bit.
  411.     beq aclr3        ; It's clear, clear the bit.
  412.     bset d0,(a1)        ; Set the bit.
  413.     bra askip3        ; Next plane.
  414. aclr3    bclr d0,(a1)        ; Clear the bit.
  415. askip3    addq.l #2,a1        ; Increment address.
  416.  
  417.     btst #3,d2        ; Check out the bit.
  418.     beq aclr4        ; It's clear, clear the bit.
  419.     bset d0,(a1)        ; Set the bit.
  420.     bra askip4        ; Next plane.
  421. aclr4    bclr d0,(a1)        ; Clear the bit.
  422.  
  423. askip4    rts            ; All done, return.
  424.  
  425. *    Assembler Line-A Replacement Point Tester (low res _only_!)
  426. *    a0 contains address of screen.  ~C:A_ptst(X&,Y&)
  427.  
  428. A_ptst    move.l a7,a1        ; Copy over stack pointer.
  429.     lea vtable(pc),a2    ; Address of vertical table.
  430.     clr.l d0        ; Make sure all of this is clear.
  431.     clr.l d1        ; Make sure all of this is clear.
  432.     clr.w d2        ; This is the return color.
  433.  
  434.     move.w 4(a1),d0        ; X coordinate.
  435.     move.w 6(a1),d1        ; Y coordinate.
  436.  
  437.     lsl.w #1,d1        ; Double Y-coord for lookup.
  438.     move.l a0,a1        ; Copy over the address.
  439.     move.w 0(a2,d1.w),d1    ; Move in the Y-offset.
  440.     add.l d1,a1        ; Add in the vertical offset.
  441.  
  442.     move.w d0,d1        ; Copy the X-coord.
  443.     lsr.w #4,d1        ; Shift down.
  444.     lsl.w #3,d1        ; Shift up.
  445.     add.l d1,a1        ; Add in the horizontal offset.
  446.  
  447.     and.w #$F,d0        ; Take just the low nibble.
  448.     eor.w #$F,d0        ; Invert it.
  449.     btst #3,d0        ; In the higher byte?
  450.     bne flowb2        ; Yes.
  451.  
  452.     addq.l #1,a1        ; Increment address.
  453.  
  454. flowb2    btst d0,(a1)        ; Check out the bit.
  455.     beq bclr1        ; It's clear, clear the bit.
  456.     bset #0,d2        ; Set the bit.
  457.     bra bskip1        ; Next plane.
  458. bclr1    bclr #0,d2        ; Clear the bit.
  459. bskip1    addq.l #2,a1        ; Increment address.
  460.  
  461.     btst d0,(a1)        ; Check out the bit.
  462.     beq bclr2        ; It's clear, clear the bit.
  463.     bset #1,d2        ; Set the bit.
  464.     bra bskip2        ; Next plane.
  465. bclr2    bclr #1,d2        ; Clear the bit.
  466. bskip2    addq.l #2,a1        ; Increment address.
  467.  
  468.     btst d0,(a1)        ; Check out the bit.
  469.     beq bclr3        ; It's clear, clear the bit.
  470.     bset #2,d2        ; Set the bit.
  471.     bra bskip3        ; Next plane.
  472. bclr3    bclr #2,d2        ; Clear the bit.
  473. bskip3    addq.l #2,a1        ; Increment address.
  474.  
  475.     btst d0,(a1)        ; Check out the bit.
  476.     beq bclr4        ; It's clear, clear the bit.
  477.     bset #3,d2        ; Set the bit.
  478.     bra bskip4        ; Next plane.
  479. bclr4    bclr #3,d2        ; Clear the bit.
  480.  
  481. bskip4    move.w d2,d0        ; Return value.
  482.     rts            ; All done.
  483.  
  484. *    The random number generator.
  485.  
  486. rnd    move.l rndseed,d1    ; Get random number seed.
  487.     move.l d1,d0        ; Make a copy.
  488.     lsl.l #4,d0        ; Shift this over.
  489.     lsr.l #3,d1        ; Shift this the other way.
  490.     eor.l d1,d0        ; XOR them together.
  491.     move.l $4BC.w,d1    ; Get system timer.
  492.     eor.l d1,d0        ; XOR the system timer.
  493.     move.l d0,rndseed    ; Save it for next time.
  494.     lsr #8,d0        ; Shift this down, please.
  495.  
  496.     rts            ; Done.
  497.  
  498. *    Other variables.
  499.  
  500. initmsg    dc.b $1B,'p  -F-A-Z-E-  ',$1B,'q',$D,$A
  501.     dc.b ' v1.0 by dmj',$D,$A,$D,$A,0
  502. errmsg    dc.b 7,'Not usable in high rez!',$D,$A,$D,$A,0
  503. okmsg    dc.b '** Installed **',$D,$A,$D,$A,0
  504.  
  505.     even
  506.  
  507. *    The Vertical Offset Table - faster than muls.
  508.  
  509. vtable    dc.b $00,$00,$00,$A0,$01,'@',$01,$E0,$02,$80,$03,' ',$03,$C0,$04,'`'
  510.     dc.b $05,$00,$05,$A0,$06,'@',$06,$E0,$07,$80,$08,' ',$08,$C0,$09,'`'
  511.     dc.b $0A,$00,$0A,$A0,$0B,'@',$0B,$E0,$0C,$80,$0D,' ',$0D,$C0,$0E,'`'
  512.     dc.b $0F,$00,$0F,$A0,$10,'@',$10,$E0,$11,$80,$12,' ',$12,$C0,$13,'`'
  513.     dc.b $14,$00,$14,$A0,$15,'@',$15,$E0,$16,$80,$17,' ',$17,$C0,$18,'`'
  514.     dc.b $19,$00,$19,$A0,$1A,'@',$1A,$E0,$1B,$80,$1C,' ',$1C,$C0,$1D,'`'
  515.     dc.b $1E,$00,$1E,$A0,$1F,'@',$1F,$E0,' ',$80,'! !',$C0,'"`#',$00,'#'
  516.     dc.b $A0,'$@$',$E0,'%',$80,'& &',$C0,$27,'`(',$00,'(',$A0,')@)',$E0,'*'
  517.     dc.b $80,'+ +',$C0,',`-',$00,'-',$A0,'.@.',$E0,'/',$80,'0 0',$C0,'1`'
  518.     dc.b '2',$00,'2',$A0,'3@3',$E0,'4',$80,'5 5',$C0,'6`7',$00,'7',$A0
  519.     dc.b '8@8',$E0,'9',$80,': :',$C0,';`<',$00,'<',$A0,'=@=',$E0,'>',$80
  520.     dc.b '? ?',$C0,'@`A',$00,'A',$A0,'B@B',$E0,'C',$80,'D D',$C0,'E`F'
  521.     dc.b $00,'F',$A0,'G@G',$E0,'H',$80,'I I',$C0,'J`K',$00,'K',$A0,'L@L'
  522.     dc.b $E0,'M',$80,'N N',$C0,'O`P',$00,'P',$A0,'Q@Q',$E0,'R',$80,'S S'
  523.     dc.b $C0,'T`U',$00,'U',$A0,'V@V',$E0,'W',$80,'X X',$C0,'Y`Z',$00,'Z'
  524.     dc.b $A0,'[@[',$E0,'\',$80,'] ]',$C0,'^`_',$00,'_',$A0,'`@`',$E0,'a'
  525.     dc.b $80,'b b',$C0,'c`d',$00,'d',$A0,'e@e',$E0,'f',$80,'g g',$C0,'h`'
  526.     dc.b 'i',$00,'i',$A0,'j@j',$E0,'k',$80,'l l',$C0,'m`n',$00,'n',$A0
  527.     dc.b 'o@o',$E0,'p',$80,'q q',$C0,'r`s',$00,'s',$A0,'t@t',$E0,'u',$80
  528.     dc.b 'v v',$C0,'w`x',$00,'x',$A0,'y@y',$E0,'z',$80,'{ {',$C0,'|`' 
  529.  
  530. svscrn
  531.  
  532. *    Well, you made it to the end.  I realize this probably isn't the
  533. *    most efficient assembly code around, but I don't normally write
  534. *    self-contained assembly programs.  The only reason I started was
  535. *    to write TSRs.  If you have any suggestions for improving the
  536. *    code, I'd be glad to hear it.
  537. *
  538. *        Damien M. Jones
  539. *        PSC 8 Box 657
  540. *        APO AE 09109
  541. *
  542. *    Be sure to check out BoinkSave, available on GEnie; you can
  543. *    probably find it on the other networks as well.
  544. *
  545. *        -dmj
  546.